package com.qfedu.edu.seckill.config;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;

@SpringBootConfiguration
@ConditionalOnProperty(name = "framework.config.mq",havingValue = "true")
public class RabbitMQConfig {

    /**
     * 申明操作MQ的对象
     * @param connectionFactory
     * @return
     */
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);
        rabbitTemplate.setChannelTransacted(true);
        return rabbitTemplate;
    }

    @Bean
    public Queue mysqlQueue(){
        return new Queue("mysqlQueue", true, false, false, null);
    }

    /**
     * 订单队列
     * @return
     */
    @Bean
    public Queue orderQueue(){
        return new Queue("orderQueue", true, false, false, null);
    }


    /**
     * 减库存的队列
     * @return
     */
    @Bean
    public Queue reduceQueue(){
        return new Queue("reduceQueue", true, false, false, null);
    }



    //下面配置异常处理机制
    /**
     * 配置的是异常的业务队列
     * @return
     */
    @Bean
    public Queue exceptionBusinessQueue(){
        return new Queue("exceptionBusinessQueue", true, false, false, null);
    }

    /**
     * 配置的是异常业务交换机
     * @return
     */
    @Bean
    public FanoutExchange exceptionBusinessFanoutExchange(){
        return new FanoutExchange("exceptionBusinessFanoutExchange");
    }

    /**
     * 把异常业务队列绑定到 异常交换机中
     * @param exceptionBusinessQueue
     * @param exceptionBusinessFanoutExchange
     * @return
     */
    @Bean
    public Binding binding1(Queue exceptionBusinessQueue,FanoutExchange exceptionBusinessFanoutExchange){
        //把上面的队列 绑定到交换机
        return BindingBuilder.bind(exceptionBusinessQueue).to(exceptionBusinessFanoutExchange);
    }

    //配置异常处理逻辑了
    //重试失败之后 我们的消息 直接进入 exceptionBusinessFanoutExchange交换机中
    @Bean
    public MessageRecoverer messageRecoverer(RabbitTemplate rabbitTemplate){
        return new RepublishMessageRecoverer(rabbitTemplate,"exceptionBusinessFanoutExchange","");
    }


    //在这里我们需要为MQ配置一个通道

    //申明一个通道
    /**
     * 申明这个通道的目的是为了找到队列中的消费者的个数 以及消息的个数
     * @param connectionFactory
     * @return
     */
    @Bean
    public Channel channel(ConnectionFactory connectionFactory){
        return connectionFactory.createConnection().createChannel(true);
    }




}

